/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pt.ipleiria.estg.mei.rc.view;

import java.awt.Component;
import java.awt.Container;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import net.boplicity.xmleditor.XmlTextPane;
import org.w3c.dom.Node;
import pt.ipleiria.estg.mei.rc.Informable;
import pt.ipleiria.estg.mei.rc.SemanticIntegrationProcessor;
import pt.ipleiria.estg.mei.rc.model.ResultsTableModel;
import pt.ipleiria.estg.mei.rc.xml.XMLUtils;

/**
 *
 * @author cesperanc
 */
public class SemanticIntegration extends javax.swing.JFrame {

    /**
     * Creates new form SemanticIntegration
     */
    public SemanticIntegration() {
        initComponents();
        initCustomComponents();
    }

    /**
     * Add our custom components
     */
    private void initCustomComponents() {
        // Dataset 1 container
        txtDataSet1 = new XmlTextPane();
        txtDataSet1.setName("txtDataset1"); // NOI18N
        txtDataSet1.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtDataSetFocusGained(evt);
            }

            @Override
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtDataSetFocusLost(evt);
            }
        });
        spDataSet1.setViewportView(txtDataSet1);

        // Dataset 2 container
        txtDataSet2 = new XmlTextPane();
        txtDataSet2.setName("txtDataset2"); // NOI18N
        txtDataSet2.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtDataSetFocusGained(evt);
            }

            @Override
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtDataSetFocusLost(evt);
            }
        });
        spDataSet2.setViewportView(txtDataSet2);

        // Update status on events
        this.informable = new Informable() {
            @Override
            public void messageChanged(String message) {
                pbStatus.setString(message);
            }
        };
        
        // Results table
        tableResults = new ResultsTable();
        tableResults.setName("tblResults");
        tableResults.setAutoCreateRowSorter(true);
        spResults.setViewportView(tableResults);
        
        updateFindMatchButtonState();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        fileChooser = new javax.swing.JFileChooser();
        panel = new javax.swing.JPanel();
        splitPane = new javax.swing.JSplitPane();
        panelLeft = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel1 = new javax.swing.JPanel();
        lblDataSet1 = new javax.swing.JLabel();
        btnLoadDataSet1 = new javax.swing.JButton();
        jPanel5 = new javax.swing.JPanel();
        spDataSet1 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel();
        lblItemToSearch = new javax.swing.JLabel();
        cbSelectFromDataSet1 = new javax.swing.JComboBox();
        btnFindMatches = new javax.swing.JButton();
        panelRight = new javax.swing.JPanel();
        jSplitPane2 = new javax.swing.JSplitPane();
        jPanel3 = new javax.swing.JPanel();
        lblDataSet2 = new javax.swing.JLabel();
        btnLoadDataSet2 = new javax.swing.JButton();
        spDataSet2 = new javax.swing.JScrollPane();
        jPanel4 = new javax.swing.JPanel();
        lblResults = new javax.swing.JLabel();
        spResults = new javax.swing.JScrollPane();
        pbStatus = new javax.swing.JProgressBar();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("RC - Semantic Integration");
        setName("mainFrame"); // NOI18N

        splitPane.setDividerLocation(500);

        jSplitPane1.setDividerLocation(500);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        lblDataSet1.setText("Dataset to compare with:");
        lblDataSet1.setName(""); // NOI18N

        btnLoadDataSet1.setText("Load from file");
        btnLoadDataSet1.setName("btnLoadDataSet1"); // NOI18N
        btnLoadDataSet1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadDataSet1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(spDataSet1, javax.swing.GroupLayout.DEFAULT_SIZE, 461, Short.MAX_VALUE)
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spDataSet1, javax.swing.GroupLayout.DEFAULT_SIZE, 431, Short.MAX_VALUE)
                .addGap(0, 0, 0))
        );

        spDataSet1.getAccessibleContext().setAccessibleDescription("");
        spDataSet1.getAccessibleContext().setAccessibleParent(jPanel1);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(lblDataSet1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 149, Short.MAX_VALUE)
                    .addComponent(btnLoadDataSet1)
                    .addContainerGap()))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(44, 44, 44)
                .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(lblDataSet1)
                        .addComponent(btnLoadDataSet1))
                    .addContainerGap(462, Short.MAX_VALUE)))
        );

        jSplitPane1.setTopComponent(jPanel1);

        lblItemToSearch.setText("Item to search:");
        lblItemToSearch.setToolTipText("");

        cbSelectFromDataSet1.setName("cbElementsToFind"); // NOI18N
        cbSelectFromDataSet1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbSelectFromDataSet1ActionPerformed(evt);
            }
        });

        btnFindMatches.setText("Find matches");
        btnFindMatches.setName("btnMatch"); // NOI18N
        btnFindMatches.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnFindMatchesActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(cbSelectFromDataSet1, 0, 315, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(btnFindMatches))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(lblItemToSearch)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblItemToSearch)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cbSelectFromDataSet1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnFindMatches))
                .addContainerGap(97, Short.MAX_VALUE))
        );

        jSplitPane1.setRightComponent(jPanel2);

        javax.swing.GroupLayout panelLeftLayout = new javax.swing.GroupLayout(panelLeft);
        panelLeft.setLayout(panelLeftLayout);
        panelLeftLayout.setHorizontalGroup(
            panelLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelLeftLayout.createSequentialGroup()
                .addComponent(jSplitPane1)
                .addContainerGap())
        );
        panelLeftLayout.setVerticalGroup(
            panelLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1)
        );

        splitPane.setLeftComponent(panelLeft);

        jSplitPane2.setDividerLocation(400);
        jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane2.setPreferredSize(new java.awt.Dimension(591, 500));

        lblDataSet2.setText("Dataset to compare to:");
        lblDataSet2.setName(""); // NOI18N

        btnLoadDataSet2.setText("Load from file");
        btnLoadDataSet2.setName("btnLoadDataSet1"); // NOI18N
        btnLoadDataSet2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadDataSet2ActionPerformed(evt);
            }
        });

        spDataSet2.setName("spDataSet2"); // NOI18N

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spDataSet2, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel3Layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(lblDataSet2)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 132, Short.MAX_VALUE)
                    .addComponent(btnLoadDataSet2)
                    .addContainerGap()))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(53, 53, 53)
                .addComponent(spDataSet2, javax.swing.GroupLayout.DEFAULT_SIZE, 334, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel3Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(lblDataSet2)
                        .addComponent(btnLoadDataSet2))
                    .addContainerGap(362, Short.MAX_VALUE)))
        );

        jSplitPane2.setLeftComponent(jPanel3);

        lblResults.setText("Results:");
        lblResults.setToolTipText("");

        spResults.setName("spResults"); // NOI18N

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(lblResults)
                        .addGap(0, 370, Short.MAX_VALUE))
                    .addComponent(spResults))
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblResults)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(spResults, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
                .addContainerGap())
        );

        jSplitPane2.setRightComponent(jPanel4);

        javax.swing.GroupLayout panelRightLayout = new javax.swing.GroupLayout(panelRight);
        panelRight.setLayout(panelRightLayout);
        panelRightLayout.setHorizontalGroup(
            panelRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 454, Short.MAX_VALUE)
        );
        panelRightLayout.setVerticalGroup(
            panelRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 666, Short.MAX_VALUE)
        );

        splitPane.setRightComponent(panelRight);

        pbStatus.setString("");
        pbStatus.setStringPainted(true);

        javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
        panel.setLayout(panelLayout);
        panelLayout.setHorizontalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pbStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(panelLayout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(splitPane)
                    .addContainerGap()))
        );
        panelLayout.setVerticalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelLayout.createSequentialGroup()
                .addContainerGap(690, Short.MAX_VALUE)
                .addComponent(pbStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(panelLayout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE)
                    .addGap(42, 42, 42)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Load dataset 1
     *
     * @param evt
     */
    private void btnLoadDataSet1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadDataSet1ActionPerformed
        setPanelEnabled(panelLeft, false);
        setPanelEnabled(panelRight, false);
        resetStatus();

        loadToDataSet(txtDataSet1);

        setPanelEnabled(panelLeft, true);
        setPanelEnabled(panelRight, true);
    }//GEN-LAST:event_btnLoadDataSet1ActionPerformed

    /**
     * Load dataset 2
     *
     * @param evt
     */
    private void btnLoadDataSet2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadDataSet2ActionPerformed
        //txtDataSet2.setText(loadDataFromFile());
        setPanelEnabled(panelLeft, false);
        setPanelEnabled(panelRight, false);
        resetStatus();

        loadToDataSet(txtDataSet2);

        setPanelEnabled(panelLeft, true);
        setPanelEnabled(panelRight, true);
    }//GEN-LAST:event_btnLoadDataSet2ActionPerformed
    /**
     * Cache the initial value for the textarea
     *
     * @param evt
     */
    private void txtDataSetFocusGained(java.awt.event.FocusEvent evt) {                                       
        this.initialTextAreaText = ((XmlTextPane) evt.getComponent()).getText();
    }

    /**
     * Check for value changes and process the changes
     *
     * @param evt
     */
    private void txtDataSetFocusLost(java.awt.event.FocusEvent evt) {                                     
        String finalText = ((XmlTextPane) evt.getComponent()).getText();
        if (!this.initialTextAreaText.equals(finalText)) {
            loadToDataSet(((XmlTextPane) evt.getComponent()), finalText);
        }
    }
    private void btnFindMatchesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindMatchesActionPerformed
        
        Node selectedNode = XMLUtils.getElementAtIndex(txtDataSet1.getText(), cbSelectFromDataSet1.getSelectedIndex()-1);
        if(selectedNode!=null){
            List<Node> nodeList = XMLUtils.getChildNodes(txtDataSet2.getText());
            if(nodeList!=null){
                ResultsTableModel model = (ResultsTableModel) tableResults.getModel();
                model.clear();
                for(int i=0; i<nodeList.size(); i++){
                    Node node = nodeList.get(i);
                    if(node!=null){
                        String nodeName;
                        if(node.getAttributes().item(0)!=null){
                            nodeName = new StringBuilder().append(node.getNodeName()).append("_").append(node.getAttributes().item(0)).toString();
                        }else{
                            nodeName = node.getNodeName();
                        }
                        model.insertRow(i, nodeName, SemanticIntegrationProcessor.evaluateXmlNodeSimilarity(selectedNode, node), node);
                    }
                    //break;
                }
            }
        }
    }//GEN-LAST:event_btnFindMatchesActionPerformed

    private void cbSelectFromDataSet1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSelectFromDataSet1ActionPerformed
        if (!cbSelectFromDataSet1.getSelectedItem().toString().isEmpty()) {
            btnFindMatches.setEnabled(true);
        } else {
            btnFindMatches.setEnabled(true);
        }
    }//GEN-LAST:event_cbSelectFromDataSet1ActionPerformed

    /**
     * Set the state of a panel and all their components
     *
     * @param panel panel to change the state
     * @param enabled state to apply to the panel
     */
    private void setPanelEnabled(Container panel, boolean enabled) {
        panel.setEnabled(enabled);
        Component[] components = panel.getComponents();
        for (Component c : components) {
            c.setEnabled(enabled);
            if (c instanceof Container) {
                setPanelEnabled((Container) c, enabled);
            }
        }
    }

    /**
     * Reset the status of the progress bar to the default state
     */
    private void resetStatus() {
        this.updateStatus(0, "");
        btnFindMatches.setEnabled(false);
    }

    /**
     * Update the progress bar component
     *
     * @param percentage
     * @param text
     */
    private void updateStatus(int percentage, String text) {
        pbStatus.setValue(percentage);
        pbStatus.setString(text);
    }

    /**
     * Update the combobox with the data from the dataset 1
     */
    private void syncDataSet1WithCombo() {
        List<String> descriptions = XMLUtils.getRootElements(txtDataSet1.getText());
        if(descriptions!=null)
            cbSelectFromDataSet1.setModel(new DefaultComboBoxModel(descriptions.toArray()));
        //cbSelectFromDataSet1.setModel(new DefaultComboBoxModel(txtDataSet1.getText().split("\n")));
    }

    private void updateFindMatchButtonState() {
        btnFindMatches.setEnabled(!(txtDataSet1.getText().isEmpty() || txtDataSet2.getText().isEmpty()));
    }

    /**
     * Load and process a text to the textarea
     *
     * @param textArea
     * @param text
     */
    private void loadToDataSet(final XmlTextPane textArea, String text) {
        SemanticIntegrationProcessor worker = null;
        if (text != null) {
            try{
                textArea.setText(XMLUtils.prettyFormat(textArea.getText()));
                updateStatus(100, "Data set ready");
                if (textArea.getName().equals("txtDataset1")) {
                    syncDataSet1WithCombo();
                }
                
            }catch(Exception e1) {
                updateStatus(0, "Error in the XML");
                JOptionPane.showMessageDialog(this,
                e1.getLocalizedMessage(),
                "Error while formating the XML",
                JOptionPane.ERROR_MESSAGE);
                System.out.println("Error while formating the XML. (" + e1.getLocalizedMessage() + ")");
            }

            updateFindMatchButtonState();
        } else {
            textArea.setText("");
            worker = new SemanticIntegrationProcessor(loadDataFromFile(), this.informable) {
                @Override
                protected void done() {
                    try {
                        textArea.setText(get());
                        updateStatus(100, "Data set ready");

                        if (textArea.getName().equals("txtDataset1")) {
                            syncDataSet1WithCombo();
                        }

                    } catch (InterruptedException | ExecutionException e) {
                        updateStatus(0, "Error occurred: " + e.getLocalizedMessage());
                    }

                    updateFindMatchButtonState();
                }
            };
        }

        if(worker!=null){
            // A property listener used to update the progress bar
            PropertyChangeListener listener = new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent pce) {
                    if ("progress".equals(pce.getPropertyName())) {
                        pbStatus.setValue((Integer) pce.getNewValue());
                    }
                }
            };
            worker.addPropertyChangeListener(listener);

            // Start the worker.
            worker.execute();
        }
    }

    /**
     * Load the dataset to a textarea from a file
     *
     * @param textArea
     */
    private void loadToDataSet(final XmlTextPane textArea) {
        this.loadToDataSet(textArea, null);
    }

    /**
     * Load the data from a file with a filechooser window
     *
     * @return String with the file contents
     */
    private java.io.File loadDataFromFile() {
        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            return fileChooser.getSelectedFile();
        }
        return null;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(SemanticIntegration.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>


        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                SemanticIntegration si = new SemanticIntegration();
                si.setVisible(true);
            }
        });


    }
    private Informable informable;
    private String initialTextAreaText = "";
    private net.boplicity.xmleditor.XmlTextPane txtDataSet1;
    private net.boplicity.xmleditor.XmlTextPane txtDataSet2;
    private ResultsTable tableResults;
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnFindMatches;
    private javax.swing.JButton btnLoadDataSet1;
    private javax.swing.JButton btnLoadDataSet2;
    private javax.swing.JComboBox cbSelectFromDataSet1;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JLabel lblDataSet1;
    private javax.swing.JLabel lblDataSet2;
    private javax.swing.JLabel lblItemToSearch;
    private javax.swing.JLabel lblResults;
    private javax.swing.JPanel panel;
    private javax.swing.JPanel panelLeft;
    private javax.swing.JPanel panelRight;
    private javax.swing.JProgressBar pbStatus;
    private javax.swing.JScrollPane spDataSet1;
    private javax.swing.JScrollPane spDataSet2;
    private javax.swing.JScrollPane spResults;
    private javax.swing.JSplitPane splitPane;
    // End of variables declaration//GEN-END:variables
}